/**
 * @description: indexDB 在使用的时候，直接生产库，然后查看是否有表，有表添加数据或者修改数据，没有表就进行新增
 * @param databaseName => 数据库名字
 * @param table => 数据库表名字
 * @param key => 存储时候的键（indexDB是根据键值进行查询）
 * @param data => 进行新增的数据或者说是修改的数据，具体看调用方法
 * @param callback => 回调函数（indexDB是异步的，所以大部分都用回调或者Promise去执行）
 * @return {type}
 */

if (!window.localStorage.getItem("db_version")) {
  window.localStorage.setItem("db_version", 1);
}

class DB {
  constructor(databaseName) {
    this.databaseName = databaseName;
  }

  //#region 创建数据库
  _init(table, flags, callback) {
    let version = window.localStorage.getItem("db_version");

    let flag = flags;
    let indexdb;

    const request = window.indexedDB.open(this.databaseName, version);

    request.onerror = () => {
      callback &&
        callback({
          status: "error",
          mes: "打开数据库失败！",
        });
    };

    request.onsuccess = (event) => {
      indexdb = event.target.result;

      if (flag == true) {
        version = window.localStorage.getItem("db_version") * 1 + 1;
        window.localStorage.setItem("db_version", version);
      } else {
        version = parseInt(window.localStorage.getItem("db_version"));
      }

      if (indexdb.objectStoreNames.length > 0) {
        flag = true;
      }

      indexdb.isCreate = flag;

      flag = false;

      callback && callback(indexdb);
    };

    request.onupgradeneeded = (event) => {
      indexdb = event.target.result;
      if (!indexdb.objectStoreNames.contains(table)) {
        if (flag) {
          indexdb.createObjectStore(table, {
            keyPath: "id",
          });
        }
      }
    };
  }
  //#endregion

  selectOneData(table, key) {
    return new Promise((resovle, reject) => {
      this._init(table, false, (db) => {
        if (db.isCreate == false) {
          reject({
            status: "error",
            mes: "获取数据失败！",
          });
          db.close();
          return;
        } else {
          const transaction = db.transaction(table, "readwrite");
          const store = transaction.objectStore(table);

          const request = store.get(key);

          request.onsuccess = (e) => {
            try {
              const resultData = e.target.result;
              resovle({
                status: "success",
                dataBase: this.databaseName,
                table: table,
                data: resultData.value,
              });
            } catch (error) {
              reject({
                status: "error",
                mes: "数据读取失败！数据库中没有该数据！",
              });
            }
          };
          request.onerror = () => {
            reject({
              status: "error",
              mes: "数据读取失败！",
            });
          };
        }
        db.close();
      });
    });
  }

  selectAllData(table, key) {
    return new Promise((resovle, reject) => {
      this._init(table, false, (db) => {
        if (db.isCreate == false) {
          reject({
            status: "error",
            mes: "获取数据失败！",
          });
          db.close();
          return;
        } else {
          const transaction = db.transaction(table, "readwrite");
          const request = transaction.objectStore(table);

          const list = []; // 存放所有的数据

          request.openCursor().onsuccess = (e) => {
            try {
              const cursor = e.target.result;

              if (cursor) {
                const value = cursor.value;
                // console.log('New value:', value);
                list.push(value);
                cursor.continue();
              } else {
                console.log("Finished iterating");
                resovle({
                  status: "success",
                  dataBase: this.databaseName,
                  table: table,
                  data: list,
                });
              }
            } catch (error) {
              reject({
                status: "error",
                mes: "数据读取失败！数据库中没有该数据！",
              });
            }
          };
          request.onerror = () => {
            reject({
              status: "error",
              mes: "数据读取失败！",
            });
          };
        }
        db.close();
      });
    });
  }

  insertData(table, key, data) {
    return new Promise((resovle, reject) => {
      this._init(table, true, (db) => {
        try {
          const createData = [
            {
              id: key,
              value: data,
            },
          ];

          const transaction = db.transaction(table, "readwrite");
          const store = transaction.objectStore(table);
          for (let i = 0; i < createData.length; i++) {
            store.add(createData[i]);
          }

          resovle({
            status: "success",
            dataBase: this.databaseName,
            table: table,
            data: createData,
          });
        } catch (err) {
          reject({
            status: "error",
            mes: "数据写入失败！",
          });
        }
      });
    });
  }

  deleteData(table, key, callback) {
    return new Promise((resovle, reject) => {
      this._init(table, false, (db) => {
        if (db.isCreate == false) {
          reject({
            status: "error",
            mes: "删除数据失败！",
          });
          db.close();
          return;
        } else {
          const transaction = db.transaction(table, "readwrite");
          const store = transaction.objectStore(table);

          // 先获取
          const getresult = store.get(key);

          const promise = new Promise((resovled) => {
            getresult.onsuccess = (e) => {
              resovled(e.target.result);
              db.close();
            };
          });
          promise.then((res) => {
            // 删除操作
            const result = store.delete(key);

            if (res != undefined) {
              result.onsuccess = () => {
                resovle({
                  status: "success",
                  mes: "删除成功！",
                });
              };

              result.onerror = () => {
                reject({
                  status: "error",
                  mes: "删除失败！",
                });
              };
            } else {
              reject({
                status: "error",
                mes: "数据库中该数据已经不存在！",
              });
            }
            db.close();
          });
        }
      });
    });
  }

  updateData(table, key, data, callback) {
    this._init(table, true, (db) => {
      try {
        const updateData = {
          id: key,
          value: data,
        };

        const transaction = db.transaction(table, "readwrite");
        const store = transaction.objectStore(table);
        store.put(updateData);

        callback &&
          callback({
            status: "success",
            dataBase: this.databaseName,
            table: table,
            data: updateData,
          });
      } catch (error) {
        callback &&
          callback({
            status: "error",
            mes: "更新写入失败！",
          });
      }
      db.close();
    });
  }

  clearTable(table, callback) {
    this._init(table, true, (db) => {
      const transaction = db.transaction(table, "readwrite");
      const store = transaction.objectStore(table);

      const result = store.clear();

      result.onsuccess = () => {
        let successmsg = {
          status: "success",
          msg: "数据表" + table + "清空成功！",
        };
        callback && callback(successmsg);
      };
      result.onerror = () => {
        let successmsg = {
          status: "success",
          msg: "数据表" + table + "清空失败！",
        };
        callback && callback(successmsg);
      };
    });
  }
}

let instance = null;
function getInstance(databaseName) {
  if (!instance) {
    if (!databaseName) return;
    instance = new DB(databaseName);
  }
  return instance;
}

export default getInstance;

// 实例调用方法
/*
import getDb from "./db.js";
const db = getDb("TestDBName");


// 插入数据-增
db.insertData("users", 'uuid', { name: "Tom Yun" }, (res) => {
  console.log('insertData', res);
});

// 获取数据-查
db.selectData("users", 'uuid', (res) => {
  console.log('selectData', res);
});

// 删除数据-删
db.deleteData("users", 'uuid', (res) => {
  console.log("deleteData", res);
});

//修改数据-改
db.updateData("users", 'uuid', { name: "timly" }, (res) => {
  console.log('updateData', res);
});

// 清空表数据，不是清库
db.clearTable((res) => {
  console.log("clearTable", res);
});
*/
